﻿using System;
using System.Linq;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;
using static System.Collections.Specialized.BitVector32;

namespace TK.TSocket
{
    /// <summary>
    /// 对外tcp socker server,可监听多个端口
    /// </summary>
    public interface ITcpSocketServer : IDisposable
    {
        /// <summary>
        /// ITcpService
        /// </summary>
        ITcpService TcpService { get; }

        /// <summary>
        /// socket服务启动
        /// </summary>
        /// <param name="receiveData">数据接收</param>
        ITcpSocketServer Start(IReceiveData receiveData);

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="clientId">client唯一码</param>
        /// <param name="data">数据</param>
        Task SendData(string clientId, byte[] data);
    }

    /// <summary>
    /// 对外tcp socker server,可监听多个端口
    /// </summary>
    public class TcpSocketServer : ITcpSocketServer
    {
        private TcpService _tcpService;
        private TouchSocketConfig _touchConfig;
        private readonly Action<TcpSocketServerConfig> _action;

        /// <summary>
        /// ctor 假如未设置任何监听端口，默认监听50000端口
        /// </summary>
        public TcpSocketServer(Action<TcpSocketServerConfig> action)
        {
            _action = action;       
        }

        public ITcpService TcpService => _tcpService;

        /// <summary>
        /// tcp socket服务启动
        /// </summary>
        public ITcpSocketServer Start(IReceiveData receiveData)
        {
            if (receiveData == null)
            {
                throw new ArgumentNullException(nameof(receiveData));
            }
            _tcpService = new TcpService();
            InitConfig(_action);
            _touchConfig.ConfigureContainer(container =>
            {
                container.RegisterSingleton<IReceiveData>(receiveData);
            })
            .ConfigurePlugins(pluginManager =>
            {
                pluginManager.Add<InitHandlerPlug>();
                pluginManager.Add<ReceiveDataPlug>();
            });
            _tcpService.Setup(_touchConfig).Start();
            return this;
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="clientId">client唯一码</param>
        /// <param name="data">数据</param>
        public Task SendData(string clientId, byte[] data)
        {
            return _tcpService.SendAsync(clientId, data);
        }

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            _tcpService.SafeDispose();
        }

        #region private methods
        /// <summary>
        /// 初始化socket config
        /// </summary>
        private void InitConfig(Action<TcpSocketServerConfig> action)
        {
            TcpSocketServerConfig tcpConfig = new TcpSocketServerConfig();
            action?.Invoke(tcpConfig);
            _touchConfig = new TouchSocketConfig();
            _touchConfig.UseDelaySender();
            _touchConfig.ConfigureContainer(container =>
            {
                container.RegisterSingleton<TcpSocketServerConfig>(tcpConfig);
            });
            tcpConfig.AdvanceAction?.Invoke(_touchConfig);
            _touchConfig.UsePlugin().UseReuseAddress();
            if (tcpConfig.IpHostList.Any())
            {
                _touchConfig.SetListenIPHosts(tcpConfig.IpHostList.ToArray());
            }

            if (_tcpService.Monitors == null || _tcpService.Monitors.Length == 0)
            {
                _touchConfig.SetListenIPHosts(new IPHost[] { new IPHost(50000) });
            }
        }
        #endregion
    }
}
